package com.xmb.common.exception;

import com.alibaba.fastjson.JSON;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.xmb.common.entity.structure.Result;
import com.xmb.common.log.LoggerInterface;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.Optional;

/**
 * Created by waisam on 2017/3/23.
 */
@Component
public class ExceptionStackTraceResolver implements HandlerExceptionResolver,LoggerInterface {

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        String exceptionMessage = ex.getMessage();
        StringBuilder stackTraceInfo = new StringBuilder(StringUtils.isBlank(exceptionMessage) ? ex.getClass().getName() : exceptionMessage);
        StackTraceElement[] trace = Optional.ofNullable(ex.getStackTrace()).orElse(new StackTraceElement[]{});
        for (StackTraceElement traceElement : trace) {
            stackTraceInfo.append("\n").append("\tat ").append(traceElement.toString());
        }
        logger.error(stackTraceInfo.toString());
        response.setCharacterEncoding(Charset.forName("UTF-8").name());
        response.setContentType("application/json");
        Result result = Result.error("系统错误，请稍后重试。");
        // 单独处理微信的异常信息
        if (ex instanceof WxPayException) {
            result = Result.error(ex.getMessage());
        } else {
            if (!(ex instanceof BusinessException)) {
                logger.error(exceptionMessage, ex);
            } else  {
                result = Result.error(exceptionMessage);
            }
        }
        try(PrintWriter writer = response.getWriter()) {
            writer.print(JSON.toJSONString(result));
        } catch (IOException e) {
            logger.error(e.getMessage(), ex);
        }
        return new ModelAndView();
    }
}
